import { useEffect } from "react";
import type { DecoratableTypes } from "./Context.js";
import { useComposition } from "./Context.js";
import { useCompositionScope } from "~/CompositionScope.js";
import type { ComposeWith, Decoratable, Enumerable } from "./types.js";

export interface ComposeProps {
    function?: DecoratableTypes;
    component?: DecoratableTypes;
    with: ComposeWith;
}

export const Compose = (props: ComposeProps) => {
    const { composeComponent } = useComposition();
    const { scope, inherit } = useCompositionScope();

    const targetFn = (props.function ?? props.component) as Decoratable;

    useEffect(() => {
        if (!targetFn) {
            console.warn("You must provide a function or a component to compose with!", props);
        }
        if (typeof targetFn.original === "undefined") {
            console.warn(
                `You must make your function "${
                    targetFn.originalName ?? targetFn.name
                }" composable, by using the makeDecoratable() function!`
            );

            return;
        }

        const decorators = Array.isArray(props.with) ? props.with : [props.with];
        return composeComponent(
            targetFn.original,
            decorators as Enumerable<ComposeWith>,
            scope[scope.length - 1],
            inherit
        );
    }, [props.with]);

    return null;
};
